﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using Abreu.Profile.Database;
using Abreu.Profile.ObjectClasses;
using System.Collections.ObjectModel;
using System.Data.Linq;
using System.Windows;
using System.Resources;

namespace Abreu.Profile.Classes
{
    public class MenuTree : IDisposable
    {
        #region Class Members
        TreeView _menuTree = new TreeView();
        TreeView _menuTab = new TreeView();
        TabControl _menuTabControl = new TabControl();
        CorpAbreuDataContext _corpAbreuDC = new CorpAbreuDataContext();
        Dictionary<int, int> _dicMenuApplications = new Dictionary<int, int>();
        Dictionary<String, int> _dicApplicationsParents = new Dictionary<String, int>();
        Collection<int> _listMenuParentsIds = new Collection<int>();
        #endregion

        #region Commented code for building tree menu recursively
        //public TreeView BuildMenu(Collection<Permission> listPermission)
        //{   
        //    //Build first Node of MenuTree
        //    for (int i = 0; i < listPermission.Count; i++)
        //    {
        //        var objMenuItem = _corpAbreuDC.p_MenuPermission_SEL(listPermission[i].MenuId);

        //        foreach(p_MenuPermission_SELResult resMenuItem in objMenuItem)
        //        {
        //            TreeNode node;
        //            node = _menuTree.Nodes.Add(resMenuItem.Name);
        //            if (resMenuItem.PrecedentMenuId != null)
        //                BuildChildNodes(node, resMenuItem.PrecedentMenuId);
        //        }
        //    }
        //    return _menuTree;
        //}

        //private void BuildChildNodes(TreeNode node, int? precendentMenuId)
        //{
        //    TreeNode childNode = null;

        //    //Get precendentMenuId info
        //    var objMenuItem = _corpAbreuDC.p_MenuPermission_sel(precendentMenuId);

        //    foreach (p_MenuPermission_selResult resMenuItem in objMenuItem)                   
        //    {
        //        childNode = node.Nodes.Add(resMenuItem.Name);
        //        if (resMenuItem.PrecedentMenuId != null)
        //            BuildChildNodes(childNode, resMenuItem.PrecedentMenuId);                             
        //    }
        //} 
        #endregion

        #region Public Methods
        /// <summary>
        /// Builds the treeview control
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="sectionId"></param>
        /// <param name="categoryId"></param>
        /// <returns>TreeView control</returns>
        public TabControl BuildMenu(Collection<PermissionProfile> listPermission)
        {
            for (int i = 0; i < listPermission.Count; i++)
            {
                if (listPermission[i].DenyPermission == null || listPermission[i].DenyPermission == false)
                {
                    //Get Menu Info with P_MenuPermission_sel
                    var objMenuItem = _corpAbreuDC.P_GetMenuPermissionInfo(listPermission[i].MenuId);

                    foreach (P_GetMenuPermissionInfoResult resObjMenuItem in objMenuItem)
                    {
                        //Creates a pair dictionary Menu/Application Id's
                        _dicMenuApplications.Add(resObjMenuItem.MenuId, resObjMenuItem.ApplicationId);

                        if (resObjMenuItem.Level == 0)
                        {
                            //Build first Node of MenuTree
                            TreeViewItem treeNode = new TreeViewItem();
                            treeNode.Header = resObjMenuItem.Name;
                            treeNode.Tag = resObjMenuItem.MenuId;
                            _listMenuParentsIds.Add(resObjMenuItem.MenuId);
                            _menuTree.Items.Add(treeNode);

                            //Get ChildNodes
                            BuildChildNodes(treeNode, listPermission, resObjMenuItem.MenuId);
                        }
                    }
                }
            }

            BuildMenuTab();
            _menuTabControl = BuilTabHeadersMenu();

            //Returns menu
            return _menuTabControl;
        }

        /// <summary>
        /// Dispose members of class
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        } 
        #endregion

        #region Private Methods
        private TabControl BuildTabContentMenu()
        {
            //In each tabItem create a treeview with her dependencies (app's and menus)
            for (int i = 0; i < _menuTabControl.Items.Count; i++)
            {
                TabItem tabItem = (TabItem)_menuTabControl.Items[i];
                //Get the application Id foreach tabpage created
                if (_dicApplicationsParents.Keys.Contains(tabItem.Header.ToString()))
                {
                    int appId = _dicApplicationsParents[tabItem.Header.ToString()];

                    for (int j = 0; j < _menuTab.Items.Count; j++)
                    {
                        TreeViewItem menuItem = (TreeViewItem)_menuTab.Items[j];
                        //If is the parent node and is the one already created as tabPage
                        if (tabItem.Header.ToString() == menuItem.Header.ToString())
                        {
                            //Obtain the childnode of the parent one and add it to the tab page control that represents the parent application ID
                            TreeView auxTree = new TreeView();

                            _menuTab.Items.Remove(menuItem);
                            auxTree.Items.Add(menuItem);

                            //Foreach relation between menu Id and application Id moves the node of menu tree to the new menu Tab
                            foreach (var pair in _dicMenuApplications)
                            {
                                if (pair.Value == appId)
                                {
                                    for (int k = 0; k < _listMenuParentsIds.Count; k++)
                                    {
                                        for (int l = 0; l < _menuTree.Items.Count; l++)
                                        {
                                            TreeViewItem treeViewItemAux = (TreeViewItem)_menuTree.Items[l];
                                            if (_listMenuParentsIds[k] == (int)treeViewItemAux.Tag)
                                            {
                                                if ((int)treeViewItemAux.Tag == pair.Key)
                                                {
                                                    //Detach the item from menu Tree so that can be added to the new menu tree created
                                                    _menuTree.Items.Remove(treeViewItemAux);
                                                    menuItem.Items.Add(treeViewItemAux);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
        
                            Grid grdTab = (Grid)tabItem.Content;
                            grdTab.Width = double.NaN;
                            auxTree.Width = 250;
                            grdTab.Children.Add(auxTree); // Add to the grid
                            Grid.SetRow(auxTree, 0); // Specify row for previous grid addition
                            Grid.SetColumn(auxTree, 0); // Specity column for previous grid addition
                            tabItem.Content = grdTab;
                        }
                    }
                }
            }

            //Returns menu tabControl
            return _menuTabControl;
        }

        private TabControl BuilTabHeadersMenu()
        {
            foreach (var pair in _dicApplicationsParents)
            {
                TabItem tabItem = new TabItem();

                tabItem.Header = pair.Key;
                Grid grdTab = new Grid();

                grdTab.HorizontalAlignment = HorizontalAlignment.Stretch;
                grdTab.VerticalAlignment = VerticalAlignment.Stretch;

                // Set the column and row definitions
                grdTab.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0, GridUnitType.Auto) });
                grdTab.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
                grdTab.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });

                tabItem.Content = grdTab;

                _menuTabControl.Items.Add(tabItem);
            }

            _menuTabControl = BuildTabContentMenu();

            //Returns menu tabControl
            return _menuTabControl;
        }

        private void BuildMenuTab()
        {
            //Collection to make sure that there are no repeated nodes
            Collection<int> listAppId = new Collection<int>();

            foreach (KeyValuePair<int, int> pair in _dicMenuApplications)
            {
                if (!listAppId.Contains(pair.Value))
                {
                    listAppId.Add(pair.Value);

                    //Get Applications info with P_ApplicationInfo_Sel
                    var objApplicationItem = _corpAbreuDC.P_GetApplicationInfo(pair.Value);

                    foreach (P_GetApplicationInfoResult resObjApplicationItem in objApplicationItem)
                    {
                        if (resObjApplicationItem.LevelApplication == 0)
                        {
                            //Build first Node of application TabControl
                            TreeViewItem treeNode = new TreeViewItem();
                            treeNode.Header = resObjApplicationItem.Name;
                            treeNode.Tag = resObjApplicationItem.ApplicationId;

                            //Creates a pair key, value to use to create tab control
                            _dicApplicationsParents.Add(resObjApplicationItem.Name, resObjApplicationItem.ApplicationId);
                            _menuTab.Items.Add(treeNode);

                            //Get ChildNodes
                            BuildChildApplicationNodes(treeNode, resObjApplicationItem.ApplicationId);
                        }
                    }
                }
            }
        }

        private void BuildChildApplicationNodes(TreeViewItem treeNode, int applicationIdParent)
        {
            foreach (KeyValuePair<int, int> pair in _dicMenuApplications)
            {
                //Get Applications info with P_ApplicationInfo_Sel
                var objApplicationItem = _corpAbreuDC.P_GetApplicationInfo(pair.Value);

                foreach (P_GetApplicationInfoResult resObjApplicationItem in objApplicationItem)
                {
                    TreeViewItem childNode = new TreeViewItem();

                    if (resObjApplicationItem.PrecedentAplicationId != null)
                    {
                        if (resObjApplicationItem.PrecedentAplicationId == applicationIdParent)
                        {
                            //Build Child Node
                            childNode.Header = resObjApplicationItem.Name;
                            childNode.Tag = resObjApplicationItem.ApplicationId;
                            treeNode.Items.Add(childNode);

                            //Recursively gets child nodes
                            BuildChildApplicationNodes(childNode, resObjApplicationItem.ApplicationId);
                        }
                    }
                }
            }
        }

        private void BuildChildNodes(TreeViewItem node, Collection<PermissionProfile> listPermission, int menuIdParent)
        {
            for (int i = 0; i < listPermission.Count; i++)
            {
                if (listPermission[i].DenyPermission == null || listPermission[i].DenyPermission == false)
                {
                    //Get Menu Info with P_MenuPermission_Sel
                    var objMenuItem = _corpAbreuDC.P_GetMenuPermissionInfo(listPermission[i].MenuId);

                    foreach (P_GetMenuPermissionInfoResult resObjMenuItem in objMenuItem)
                    {
                        TreeViewItem childNode = new TreeViewItem();

                        if (resObjMenuItem.PrecedentMenuId != null)
                        {
                            if (resObjMenuItem.PrecedentMenuId == menuIdParent)
                            {
                                //Build Child Node
                                childNode.Header = resObjMenuItem.Name;
                                childNode.Tag = resObjMenuItem.MenuId;
                                node.Items.Add(childNode);

                                //Recursively gets child nodes
                                BuildChildNodes(childNode, listPermission, resObjMenuItem.MenuId);
                            }
                        }
                    }
                }
            }
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_corpAbreuDC != null)
                {
                    _corpAbreuDC.Dispose();
                    _corpAbreuDC = null;
                }
            }
        } 
        #endregion
    }
}
